package dao

import (
	"activity_srv/basic/config"
	l "activity_srv/basic/inits"
	__ "activity_srv/basic/proto"
	"activity_srv/handler/models"
	"activity_srv/untils"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"log"
	"strconv"
	"time"
)

// 创建发票
func CreateInvoice(in *__.CreateInvoiceReq) error {
	var invoice models.Invoice
	//查询订单是否存在
	var order models.Order
	order.Id = uint64(in.OrderId)
	err := order.GetOrderId()
	if err != nil {
		return errors.New("订单不存在")
	}

	invoice = models.Invoice{
		Title:       in.Title,
		UserId:      in.UserId,
		OrderId:     int32(in.OrderId),
		InvoicesNo:  uuid.NewString(),
		BankName:    in.BankName,
		Address:     in.Address,
		InvoiceType: in.InvoiceType,
		Amount:      float64(in.Amount),
	}
	err = invoice.CreateInvoice()
	if err != nil {
		return err
	}
	return err
}

// 查询发票
func ListInvoice(in *__.ListInvoiceReq) ([]*__.ListI, error) {
	invoice := models.Invoice{
		Id: uint64(in.Id),
	}
	list, err := invoice.ListInvoice()
	if err != nil {
		return nil, nil
	}
	var lists []*__.ListI
	for _, v := range list {
		lists = append(lists, &__.ListI{
			Id:          int32(v.Id),
			Title:       v.Title,
			UserId:      v.UserId,
			OrderId:     int64(v.OrderId),
			InvoicesNo:  v.InvoicesNo,
			BankName:    v.BankName,
			Address:     v.Address,
			InvoiceType: v.InvoiceType,
			Amount:      float32(v.Amount),
		})
	}
	return lists, err
}

// 删除发票
func DelInvoice(in *__.DelInvoiceReq) error {
	invoice := models.Invoice{
		Id: uint64(in.Id),
	}
	err := invoice.DelInvoice()
	if err != nil {
		return nil
	}
	return err
}

// 审核发票
func AuditInvoice(in *__.AuditInvoiceReq) (models.Invoice, error) {
	//查询发票是否存在
	var invoice models.Invoice
	invoice.Id = uint64(in.Id)
	err := invoice.GetInvoiceId()
	if err != nil {
		return invoice, err
	}

	if invoice.InvoiceType == 1 {
		//支付宝
		return invoice, errors.New("发票待审核中")
	}
	if invoice.InvoiceType == 2 {
		//微信
		return invoice, errors.New("发票待审核中")
	}

	if invoice.InvoiceType == 3 {
		//微信
		return invoice, errors.New("发票审核通过")
	}

	if invoice.InvoiceType == 4 {
		//支付宝
		return invoice, errors.New("发票审核不通过")
	}

	return invoice, err
}

// -------------------- 创建活动 --------------------
func CreateSeckill(in *__.CreateActivityReq) (models.Goods, error) {
	// 查询商品是否存在
	var good models.Goods
	good.Id = uint32(in.GoodsId)
	if err := good.GetGoodsId(); err != nil {
		return good, errors.New("商品不存在")
	}

	// 查询秒杀库存是否充足
	if good.GoodsStock < uint32(in.Num) {
		return good, errors.New("库存不足")
	}

	// 判断时间格式
	startTime, err := time.Parse("2006-01-02 15:04:05", in.StartTime)
	if err != nil {
		return good, errors.New("开始时间格式错误:" + err.Error())
	}
	endTime, err := time.Parse(time.DateTime, in.EndTime)
	if err != nil {
		return good, errors.New("结束时间格式错误:" + err.Error())
	}
	//创建秒秒杀商品
	activity := models.Activity{
		GoodsId:        in.GoodsId,
		UserId:         in.UserId,
		ActivityTitle:  in.ActivityTitle,
		Info:           in.Info,
		Price:          int64(in.Price),
		SeckillPrice:   int64(in.SeckillPrice),
		Stock:          in.Stock,
		GoodsStatus:    in.GoodsStatus,
		StartTime:      startTime,
		EndTime:        endTime,
		Num:            in.Num,
		ActivityStatus: in.ActivityStatus,
	}

	if err = activity.CreateActivity(); err != nil {
		return good, errors.New("创建活动失败")
	}

	// 扣减库存
	good.GoodsStock -= uint32(in.Num)
	if err = good.Update(config.DB); err != nil {
		return good, errors.New("扣减库存失败")
	}

	// 添加定时任务
	//l.AddTaskForNewActivity(activity)

	// 同步库存到 Redis
	if _, err = untils.SyncStockToRedis(int(activity.Id), int(activity.Num)); err != nil {
		return good, err
	}
	return good, nil
}

// 执行秒杀（秒杀中）
func ExecuteActivity(in *__.ExecuteActivityReq) (models.Activity, models.SeckillActivity, error) {
	var (
		activity        models.Activity
		seckillActivity models.SeckillActivity
	)
	// 1. 判断活动是否存在
	activity.Id = uint64(in.ActivityId)
	if err := activity.GetActivityId(); err != nil {
		return activity, seckillActivity, errors.New("活动商品不存在")
	}

	// 2. 检查活动时间是否有效
	now := time.Now()
	if now.Before(activity.StartTime) {
		return activity, seckillActivity, errors.New("活动未开始")
	}
	if now.After(activity.EndTime) {
		return activity, seckillActivity, errors.New("活动已结束")
	}

	// 4. 判断数据库中的库存
	if activity.Stock <= 0 {
		return activity, seckillActivity, errors.New("商品已售罄")
	}

	// 5. 扣减 Redis 库存（高性能扣减）
	if !untils.GoodsStockFormRedis(int(activity.Id)) {
		return activity, seckillActivity, errors.New("库存不足")
	}

	// 6. 创建秒杀订单
	seckillActivity = models.SeckillActivity{
		OrderNo:      "JD" + uuid.NewString(),
		UserId:       in.UserId,
		SeckillPrice: strconv.FormatInt(activity.SeckillPrice, 10),
		Num:          1,
	}

	// 8. 发送到 RabbitMQ 进行异步处理
	rabbit := l.NewRabbitMQSimple("2301a")
	body, err := json.Marshal(seckillActivity)
	if err != nil {
		// 序列化失败，回滚库存和用户状态
		untils.IncrStockToRedis(int(activity.Id))
		return activity, seckillActivity, fmt.Errorf("订单序列化失败: %w", err)
	}
	rabbit.PublishSimple(string(body))

	// 9. 扣减数据库中的库存
	activity.Stock -= 1
	if err = activity.UpdateStock(config.DB); err != nil {
		// 数据库库存扣减失败，记录日志但不影响用户体验（已通过Redis确保库存充足）
		log.Printf("更新数据库库存失败: %v", err)
	}

	return activity, seckillActivity, nil
}

// 完成秒杀活动（秒杀后）
func FinishSeckillActivity(in *__.FinishActivityReq) (models.Activity, models.Order, error) {
	var (
		activity  models.Activity
		lastOrder models.Order
	)
	// 1. 查询活动信息
	activity.Id = uint64(in.ActivityId)
	if err := activity.GetActivityId(); err != nil {
		return activity, lastOrder, errors.New("活动不存在")
	}

	// 2. 查询最新订单
	if err := config.DB.
		Where("activity_id = ? AND goods_id = ?", in.ActivityId, in.GoodsId).
		Order("id desc").
		First(&lastOrder).Error; err != nil {
		return activity, lastOrder, errors.New("订单不存在")
	}

	// 更新订单状态为已支付
	lastOrder.PayStatus = 2 // 成功
	if err := lastOrder.UpdateOrderStatus(config.DB); err != nil {
		return activity, lastOrder, errors.New("更新订单状态失败: " + err.Error())
	}

	// 4. 如果活动已结束，同步剩余库存回 MySQL
	if time.Now().After(activity.EndTime) {
		// 4.1 更新活动状态为已结束
		activity.ActivityStatus = 3 // 结束
		if err := activity.UpdateActivityStatus(config.DB); err != nil {
			// 仅记录错误，不中断流程
			log.Printf("更新活动状态失败: %v", err)
		}

		// 4.2 获取Redis中剩余库存并同步到MySQL
		redisStock := untils.GetStockFormRedis(int(activity.Id))
		if redisStock >= 0 {
			activity.Stock = int32(redisStock)
			if err := activity.UpdateStock(config.DB); err != nil {
				return activity, lastOrder, errors.New("同步库存失败: " + err.Error())
			}
		}
	}
	return activity, lastOrder, nil
}

// 启动订单消费者，从消息队列获取订单信息
func StartOrderConsumer() {
	// 创建一个新的消费者实例
	rabbit := l.NewRabbitMQSimple("2301a")
	msgs, err := rabbit.ConsumeSimple()
	if err != nil {
		log.Fatalf("Failed to register a consumer: %s", err)
	}

	// 启动协程处理消息
	go func() {
		for d := range msgs {
			log.Printf("Received a message: %s", d.Body)

			// 解析秒杀订单信息
			var seckillOrder models.SeckillActivity
			if err = json.Unmarshal(d.Body, &seckillOrder); err != nil {
				log.Printf("Failed to unmarshal seckill order: %s", err)
				continue
			}

			//go processPaidOrder(seckillOrder)
		}
	}()
	log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
}

// 展示秒杀列表
func ListActivity(in *__.ListActivityReq) ([]*__.ListA, error) {
	activity := models.Activity{
		Id: uint64(in.Id),
	}
	list, err := activity.ListActivity()
	if err != nil {
		return nil, nil
	}
	var lists []*__.ListA
	for _, v := range list {
		lists = append(lists, &__.ListA{
			GoodsId:        v.GoodsId,
			UserId:         v.UserId,
			ActivityTitle:  v.ActivityTitle,
			Info:           v.Info,
			Price:          int32(v.Price),
			SeckillPrice:   int32(v.SeckillPrice),
			Stock:          v.Stock,
			GoodsStatus:    v.GoodsStatus,
			StartTime:      v.StartTime.Format("2006-01-02 15:04:05"),
			EndTime:        v.EndTime.Format("2006-01-02 15:04:05"),
			Num:            v.Num,
			ActivityStatus: v.ActivityStatus,
			Id:             int32(v.Id),
		})
	}
	return lists, err
}

// 处理已支付的订单
func processPaidOrder(order models.Order) {
	// 1. 更新订单状态为已支付
	order.PayStatus = 1 // 1表示已支付
	if err := config.DB.Model(&models.Order{}).Where("order_no = ?", order.OrderNo).Update("pay_status", 1).Error; err != nil {
		log.Printf("Failed to update order payment status: %s", err)
		return
	}

	// 2. 更新订单状态为已支付待发货
	order.OrderStatus = 2 // 2表示已支付待发货
	if err := config.DB.Model(&models.Order{}).Where("order_no = ?", order.OrderNo).Update("order_status", 2).Error; err != nil {
		log.Printf("Failed to update order status: %s", err)
		return
	}

	// 3. 获取商品信息
	var goods models.Goods
	goods.Id = uint32(order.GoodsId)
	if err := goods.GetGoodsId(); err != nil {
		log.Printf("Failed to get goods information: %s", err)
		return
	}

	// 4. 扣减商品库存
	goods.GoodsStock -= uint32(order.GoodsNum)
	if err := goods.Update(config.DB); err != nil {
		log.Printf("Failed to update goods stock: %s", err)
		return
	}

	log.Printf("Order %s processed successfully", order.OrderNo)
}
